#Region " WikiCache Class "

''' <summary>
''' Implements a local cache for specific revisions of pages on a Wikia site.
''' </summary>
''' <remarks>
''' A WikiCache can be attached to a WikiSite to improve performance of retreiving
''' specific revisions of pages. If a cache hit is found while trying to retreive 
''' a specific revision the WikiSite can avoid a throttling mechanism applied to
''' live server requests.
''' </remarks>
Public Class WikiCache

#Region " Fields "

    ''' <summary>
    ''' The root folder on the local file system where the cache files are stored.
    ''' </summary>
    ''' <remarks></remarks>
    Private m_RootFolder As String

#End Region

#Region " Constructors "

    ''' <summary>
    ''' Creates a new WikiCache using the specified local file system folder as the root
    ''' of the cache.
    ''' </summary>
    ''' <param name="rootFolder"></param>
    ''' <remarks></remarks>
    Public Sub New(ByVal rootFolder As String)
        m_RootFolder = rootFolder
    End Sub

#End Region

#Region " Properties "

    ''' <summary>
    ''' Gets or sets the root file system folder used to store cache pages.
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property RootFolder() As String
        Get
            Return m_RootFolder
        End Get
    End Property

#End Region

#Region " Methods "

    ''' <summary>
    ''' Returns whether or not the cache contains a copy of the specified article revision.
    ''' </summary>
    ''' <param name="revisionId">
    ''' The revision id for the specific article and revision to check the presence of.
    ''' </param>
    ''' <returns>True if the page currently exists in the cache, false if not.</returns>
    ''' <remarks></remarks>
    Public Function ContainsPage(ByVal revisionId As Integer) As Boolean
        Return System.IO.File.Exists(Me.GetPageCacheFileName(revisionId))
    End Function

    ''' <summary>
    ''' Stores the specified WikiPage in the file system cache.
    ''' </summary>
    ''' <param name="value">The specific revision of the page to store.</param>
    ''' <remarks>
    ''' The page must represent a specific revision or a page. Some methods in this library return
    ''' a specific revision of a page, some methods only restore the 'latest' version of the article.
    ''' Only the former can be stored in the cache and an Exception is generated if an attempt is made
    ''' to store the latter.
    ''' </remarks>
    Public Sub StoreCachePage(ByVal value As WikiPage)
        ' validate the parameters
        If (value Is Nothing) Then Throw New System.ArgumentNullException("value")
        If (value.RevisionId = -1) Then Throw New System.ArgumentException("cannot store revisionless pages in the cache")
        ' store the page in the cache
        SerializationHelper.SerializeToFile(value, GetType(WikiPage), Me.GetPageCacheFileName(value.RevisionId))
    End Sub

    ''' <summary>
    ''' Retrieves a WikiPage previously stores using StoreCachePage.
    ''' </summary>
    ''' <param name="revisionId">The revision id of the article to retrieve.</param>
    ''' <returns></returns>
    ''' <remarks>
    ''' If the page doesn't exist in the cache an Exception is generated. Use ContainsPage to
    ''' determine whether a page is stored in the cache or not before calling this method.
    ''' </remarks>
    Public Function RetrieveCachePage(ByVal revisionId As Integer) As WikiPage
        Dim objValue As Object
        ' retrieve the page from the cache
        objValue = SerializationHelper.DeserializeFromFile(GetType(WikiPage), Me.GetPageCacheFileName(revisionId))
        ' return the result
        Return CType(objValue, WikiPage)
    End Function

    ''' <summary>
    ''' Generates a local file system file name for the specified article revision.
    ''' </summary>
    ''' <param name="revisionId">The revision id of the article to generate the file name for.</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function GetPageCacheFileName(ByVal revisionId As Integer) As String
        Return Me.RootFolder & "\pages\" & revisionId & ".page"
    End Function

#End Region

End Class

#End Region
